<template>
  <div>
    <ElRow style="margin-bottom: 16px">
      <el-button
        v-if="hasPerms('exam:paper:create')"
        type="primary"
        @click="handleAdd"
        >新增</el-button
      >
      <div style="flex: 1; display: flex; justify-content: flex-end">
        <el-select
          v-model="paperListParams.groupName"
          placeholder="请选择归属试卷组"
          clearable
          style="width: 200px; margin-right: 16px"
          @change="handleSelectGroup"
        >
          <el-option
            v-for="item in paperGroupList"
            :key="item.id"
            :label="item"
            :value="item"
          />
        </el-select>
        <el-input
          v-model="paperListParams.name"
          :prefix-icon="Search"
          placeholder="请输入试卷名称"
          style="width: 200px; margin-right: 16px"
          clearable
          @change="handleSearch"
        />
      </div>
    </ElRow>
    <ReTable
      :data="paperList"
      :columns="columns"
      :pagination="pagination"
      @current-change="handleCurrentChange"
      @size-change="handleSizeChange"
    >
      <template #action="{ row }">
        <ElRow justify="center" align="middle">
          <ElCol v-if="hasPerms('exam:paper:edit')" :span="6">
            <ElButton link type="primary" @click="handleEdit(row)">
              编辑
            </ElButton>
          </ElCol>
          <ElCol v-if="hasPerms('exam:paper:status')" :span="6">
            <ElSwitch
              v-model="row.status"
              inline-prompt
              active-text="启用"
              inactive-text="禁用"
              :active-value="1"
              :inactive-value="0"
              @change="handleSwitchChange(row)"
            />
          </ElCol>
        </ElRow>
      </template>
    </ReTable>
    <ElDialog
      v-model="dialogVisible"
      :close-on-click-modal="false"
      :title="dialogTitle"
      width="50%"
      align-center
      :destroy-on-close="true"
    >
      <ElForm
        ref="formRef"
        class="paper-form"
        :model="form"
        :rules="rules"
        label-width="100px"
      >
        <ElRadioGroup
          v-if="dialogTitle === '新增试卷'"
          v-model="addPaperType"
          style="margin: 20px"
          @change="changePaperType"
        >
          <ElRadio :label="1">随机组卷</ElRadio>
          <ElRadio :label="2">人工组卷</ElRadio>
        </ElRadioGroup>
        <ElFormItem label="试卷名" prop="name">
          <ElInput
            v-model="form.name"
            placeholder="请输入试卷名"
            style="width: 200px"
          />
        </ElFormItem>
        <ElFormItem label="归属试卷组" prop="groupName">
          <ElInput
            v-model="form.groupName"
            placeholder="请输入归属试卷组"
            style="width: 200px"
          />
        </ElFormItem>
        <div v-if="dialogTitle === '新增试卷' && addPaperType === 2">
          <ElFormItem label="题目数量" prop="questionCount">
            <ElInput
              v-model="form.questionCount"
              class="number-input"
              type="number"
              disabled
              :min="0"
              placeholder="请输入每卷题目数量"
            />
          </ElFormItem>
          <ElFormItem label="单选题分值" prop="singleScore">
            <ElInput
              v-model="form.singleScore"
              class="number-input"
              type="number"
              :min="1"
              placeholder="请输入单选题分值"
            />
          </ElFormItem>
          <ElFormItem>
            <div style="display: flex; flex-flow: column; width: 100%">
              <ElButton
                style="width: 120px; margin-bottom: 12px"
                type="primary"
                @click="addSingleChoiceQuestion('1', true)"
              >
                添加单选题
              </ElButton>
              <ReTable
                :data="form.singleChoiceQuestions"
                height="auto"
                :columns="singleChoiceColumns"
                show-index
              />
            </div>
          </ElFormItem>
          <ElFormItem label="多选题分值" prop="multipleScore">
            <ElInput
              v-model="form.multipleScore"
              class="number-input"
              type="number"
              :min="1"
              placeholder="请输入多选题分值"
            />
          </ElFormItem>
          <ElFormItem>
            <div style="display: flex; flex-flow: column; width: 100%">
              <ElButton
                style="width: 120px; margin-bottom: 12px"
                type="primary"
                @click="addSingleChoiceQuestion('2', true)"
              >
                添加多选题
              </ElButton>
              <ReTable
                :data="form.multipleChoiceQuestions"
                height="auto"
                :columns="singleChoiceColumns"
                show-index
              />
            </div>
          </ElFormItem>
          <ElFormItem label="填空题分值" prop="blankScore">
            <ElInput
              v-model="form.blankScore"
              class="number-input"
              type="number"
              :min="1"
              placeholder="请输入填空题分值"
            />
          </ElFormItem>
          <ElFormItem>
            <div style="display: flex; flex-flow: column; width: 100%">
              <ElButton
                style="width: 120px; margin-bottom: 12px"
                type="primary"
                @click="addSingleChoiceQuestion('3', true)"
              >
                添加填空题
              </ElButton>
              <ReTable
                :data="form.fillBlankQuestions"
                height="auto"
                :columns="singleChoiceColumns"
                show-index
              />
            </div>
          </ElFormItem>
          <ElFormItem label="总分" prop="totalScore">
            <ElInput
              v-model="form.totalScore"
              class="number-input"
              type="number"
              disabled
              :min="0"
              placeholder="总分"
            />
          </ElFormItem>
        </div>
        <div v-if="dialogTitle === '新增试卷' && addPaperType === 1">
          <ElFormItem label="试卷套数" prop="paperCount">
            <ElInput
              v-model="form.paperCount"
              class="number-input"
              type="number"
              :min="1"
              placeholder="请输入试卷套数"
            >
              <template #append>套</template>
            </ElInput>
          </ElFormItem>
          <ElFormItem label="每卷题目数量" prop="questionCount">
            <ElInput
              v-model="form.questionCount"
              class="number-input"
              type="number"
              disabled
              :min="0"
              placeholder="请输入每卷题目数量"
            />
          </ElFormItem>
          <ElFormItem label="题型分配" prop="questionScore">
            <div
              style="
                display: flex;
                align-items: center;
                justify-content: space-between;
              "
            >
              <div style="flex: 1; display: flex; align-items: center">
                <div
                  style="margin-right: 5px; display: flex; white-space: nowrap"
                >
                  单选
                </div>
                <ElInput
                  v-model="form.singleCount"
                  style="width: 100px"
                  type="number"
                  :min="0"
                  placeholder="单选题数量"
                />
                <span class="count-unit" style="margin-left: 5px"> 个</span>
              </div>
              <div
                style="
                  flex: 1;
                  display: flex;
                  align-items: center;
                  margin-left: 20px;
                "
              >
                <div
                  style="margin-right: 5px; display: flex; white-space: nowrap"
                >
                  多选
                </div>
                <ElInput
                  v-model="form.multipleCount"
                  style="width: 100px"
                  type="number"
                  :min="0"
                  placeholder="多选题数量"
                />
                <span class="count-unit" style="margin-left: 5px"> 个</span>
              </div>
              <div
                style="
                  flex: 1;
                  display: flex;
                  align-items: center;
                  margin-left: 20px;
                "
              >
                <div
                  style="margin-right: 5px; display: flex; white-space: nowrap"
                >
                  填空
                </div>
                <ElInput
                  v-model="form.blankCount"
                  style="width: 100px"
                  type="number"
                  :min="0"
                  placeholder="填空题数量"
                />
                <span class="count-unit" style="margin-left: 5px"> 个</span>
              </div>
            </div>
          </ElFormItem>
          <ElFormItem label="每题分值" prop="questionScore">
            <div
              style="
                display: flex;
                align-items: center;
                justify-content: space-between;
              "
            >
              <div style="flex: 1; display: flex; align-items: center">
                <div
                  style="margin-right: 5px; display: flex; white-space: nowrap"
                >
                  单选
                </div>
                <ElInput
                  v-model="form.singleScore"
                  style="width: 100px"
                  type="number"
                  :min="0"
                  placeholder="单选分值"
                />
                <span class="count-unit" style="margin-left: 5px"> 分</span>
              </div>
              <div
                style="
                  flex: 1;
                  display: flex;
                  align-items: center;
                  margin-left: 20px;
                "
              >
                <div
                  style="margin-right: 5px; display: flex; white-space: nowrap"
                >
                  多选
                </div>
                <ElInput
                  v-model="form.multipleScore"
                  style="width: 100px"
                  type="number"
                  :min="0"
                  placeholder="多选题分值"
                />
                <span class="count-unit" style="margin-left: 5px"> 分</span>
              </div>
              <div
                style="
                  flex: 1;
                  display: flex;
                  align-items: center;
                  margin-left: 20px;
                "
              >
                <div
                  style="margin-right: 5px; display: flex; white-space: nowrap"
                >
                  填空
                </div>
                <ElInput
                  v-model="form.blankScore"
                  style="width: 100px"
                  type="number"
                  :min="0"
                  placeholder="填空题分值"
                />
                <span class="count-unit" style="margin-left: 5px"> 分</span>
              </div>
            </div>
          </ElFormItem>
          <ElFormItem label="总分" prop="totalScore">
            <ElInput
              v-model="form.totalScore"
              class="number-input"
              type="number"
              disabled
              :min="0"
              placeholder="总分"
            />
          </ElFormItem>
          <ElFormItem label="是否允许重复" prop="allowDuplicate">
            <ElRadioGroup v-model="form.allowDuplicate">
              <ElRadio :value="true">是</ElRadio>
              <ElRadio :value="false">否</ElRadio>
            </ElRadioGroup>
          </ElFormItem>
        </div>
        <div v-if="dialogTitle === '编辑试卷'">
          <ElFormItem label="题目" prop="paperQuestionList">
            <div style="display: flex; width: 100%; height: 500px">
              <ReTable
                style="width: 100%"
                :height="500"
                :data="form.paperQuestionList"
                :columns="paperColumns"
                show-index
              >
                <template #questionType="{ row }">
                  {{ QuestionType[row.type] }}
                </template>
              </ReTable>
            </div>
          </ElFormItem>
        </div>
      </ElForm>
      <template #footer>
        <span class="dialog-footer">
          <ElButton @click="dialogVisible = false">取消</ElButton>
          <ElButton type="primary" @click="handleConfirm">确认生成</ElButton>
        </span>
      </template>
    </ElDialog>
    <ElDialog v-model="paperGroupDialogVisible" title="选择试题" width="50%">
      <ReTable
        ref="paperSelectTableRef"
        :data="papersList"
        :pagination="paperPagination"
        :height="600"
        :columns="paperGroupColumns"
        show-index
        showSelection
        @current-change="handlePaperCurrentChange"
        @size-change="handelPaperSizeChange"
      >
        <template #status="{ row }">
          {{ QuestionType[row.type] }}
        </template>
      </ReTable>
      <template #footer>
        <span class="dialog-footer">
          <ElButton @click="handleCancelSelectPapers">取消</ElButton>
          <ElButton type="primary" @click="handleSelectPapers">确认</ElButton>
        </span>
      </template>
    </ElDialog>
  </div>
</template>

<script setup lang="ts">
import {
  getPaperList,
  getPaperDetail,
  updatePaper,
  createPaper,
  updatePaperStatus,
  getPaperGroupList,
  generatePaper
} from "@/api/paper";
import { getQuestions, QuestionType } from "@/api/question";
import { Search } from "@element-plus/icons-vue";
import ReTable from "@/components/ReTable";
import { ElMessage } from "element-plus";
import { onMounted, watch, nextTick } from "vue";
import { ref } from "vue";
import { hasPerms } from "@/utils/auth";
import { totalmem } from "os";
defineOptions({
  // name 作为一种规范最好必须写上并且和路由的name保持一致
  name: "PaperManage"
});
const paperGroupDialogVisible = ref(false);
const paperGroupColumns = [
  {
    label: "题型",
    slotName: "status",
    config: {
      width: 120
    }
  },
  {
    label: "题干",
    prop: "title"
  }
];

const addPaperType = ref(1);
const dialogVisible = ref(false);
const dialogTitle = ref("");
const formRef = ref();
const form = ref<any>({
  id: "",
  name: "",
  groupName: "",
  paperCount: "", // 试卷套数
  questionCount: 0, // 题目数量
  singleCount: 0, // 单选题数量
  multipleCount: 0, // 多选题数量
  blankCount: 0, // 填空题数量
  singleScore: 0, // 单选题分值
  multipleScore: 0, // 多选题分值
  blankScore: 0, // 填空题分值
  totalScore: 0, // 总分
  allowDuplicate: false, // 是否允许重复
  paperQuestionList: [] // 试卷题目列表
});
// 试卷列表
const paperList = ref([]);
// 分页参数
const pagination = ref({
  pageNum: 1,
  pageSize: 10,
  total: 0
});
// 试卷名称
const paperName = ref("");
// 试卷分组
const paperGroup = ref("");
// 列配置
const columns = [
  {
    label: "试卷编号",
    prop: "id"
  },
  {
    label: "试卷名称",
    prop: "name"
  },
  {
    label: "归属试卷组",
    prop: "groupName"
  },
  {
    label: "修改时间",
    prop: "gmtModified"
  },
  {
    label: "创建人",
    prop: "createBy"
  },
  {
    label: "操作",
    slotName: "action"
  }
];

// 试卷表格列
const paperColumns = [
  {
    label: "试题编号",
    prop: "questionId"
  },
  {
    label: "题型",
    slotName: "questionType"
  },
  {
    label: "分值",
    prop: "score"
  }
];

//监听校验 总分 = 单选数量*单选得分+多选数量*多选得分+填空题数量*填空题得分
const validateScore = (rule, value, callback) => {
  if (
    value !==
    form.value.singleCount * form.value.singleScore +
      form.value.multipleCount * form.value.multipleScore +
      form.value.blankCount * form.value.blankScore
  ) {
    callback(new Error("总分与题型分配中（单选+多选+填空）的得分不一致"));
  } else {
    callback();
  }
};

// 规则
const rules = {
  name: [{ required: true, message: "请输入试卷名称", trigger: "blur" }],
  groupName: [{ required: true, message: "请选择试卷分组", trigger: "blur" }],
  paperCount: [{ required: true, message: "请输入试卷套数", trigger: "blur" }],
  singleCount: [
    { required: true, message: "请输入单选题数量", trigger: "blur" }
  ],
  multipleCount: [
    { required: true, message: "请输入多选题数量", trigger: "blur" }
  ],
  blankCount: [
    { required: true, message: "请输入填空题数量", trigger: "blur" }
  ],
  singleScore: [
    { required: true, message: "请输入单选题分值", trigger: "blur" }
  ],
  multipleScore: [
    { required: true, message: "请输入多选题分值", trigger: "blur" }
  ],
  blankScore: [
    { required: true, message: "请输入填空题分值", trigger: "blur" }
  ],
  // 总分采用自定义校验
  totalSore: [{ validator: validateScore, trigger: "change" }]
};

watch(
  () => form.value,
  val => {
    handleTotalScore();
    handleQuestionCount();
  },
  { deep: true }
);

// 自动计算form中总分字段 公式为单选数量*单选得分+多选数量*多选得分+填空题数量*填空题得分
const handleTotalScore = () => {
  form.value.totalScore =
    form.value.singleCount * form.value.singleScore +
    form.value.multipleCount * form.value.multipleScore +
    form.value.blankCount * form.value.blankScore;
};

// 自动计算form中题目数量字段 公式为单选数量+多选数量+填空题数量
const handleQuestionCount = () => {
  form.value.questionCount =
    parseInt(form.value.singleCount) +
    parseInt(form.value.multipleCount) +
    parseInt(form.value.blankCount);
};
// 新增试卷
const handleAdd = () => {
  dialogTitle.value = "新增试卷";
  form.value = {
    name: "",
    group: "",
    singleCount: 0,
    multipleCount: 0,
    blankCount: 0,
    singleScore: 0,
    multipleScore: 0,
    blankScore: 0,
    totalScore: 0,
    allowDuplicate: false,
    paperQuestionList: []
  };
  dialogVisible.value = true;
};

// 编辑试卷
const handleEdit = async (row: { id: number }) => {
  dialogTitle.value = "编辑试卷";
  const result = await getPaperDetail(row.id);
  form.value = result.data;
  dialogVisible.value = true;
};

// 查询试卷列表参数
const paperListParams = ref({
  name: "",
  groupName: "",
  pageNum: 1,
  pageSize: 10
});

// 分页查询
const queryPaperList = async () => {
  try {
    const res = await getPaperList(paperListParams.value);
    paperList.value = res.data.records;
    pagination.value.total = res.data.total;
    pagination.value.pageNum = paperListParams.value.pageNum;
    pagination.value.pageSize = paperListParams.value.pageSize;
  } catch (error) {
    ElMessage.error("查询失败");
  }
};

// 切换添加试卷类型
const changePaperType = (type: string) => {
  form.value = {
    id: "",
    name: "",
    groupName: "",
    paperCount: "", // 试卷套数
    questionCount: 0, // 题目数量
    singleCount: 0, // 单选题数量
    multipleCount: 0, // 多选题数量
    blankCount: 0, // 填空题数量
    singleScore: 0, // 单选题分值
    multipleScore: 0, // 多选题分值
    blankScore: 0, // 填空题分值
    totalScore: 0, // 总分
    allowDuplicate: false, // 是否允许重复
    paperQuestionList: [] // 试卷题目列表
  };
  formRef.value.resetFields();
};

const singleChoiceColumns = [
  {
    label: "题目",
    prop: "title"
  }
];
const selectType = ref("");
// 分页数据
const paperPagination = ref({
  pageNum: 1,
  pageSize: 20,
  total: 0
});
const papersList = ref([]);
const paperSelectTableRef = ref(null);
// 添加单选题
const addSingleChoiceQuestion = (type: string, isNew?: boolean) => {
  if (isNew) {
    paperPagination.value.pageNum = 1;
  }
  getQuestions({
    pageNum: paperPagination.value.pageNum,
    pageSize: paperPagination.value.pageSize,
    type: type,
    questionNo: ""
  }).then(res => {
    papersList.value = res.data.records;
    paperPagination.value.total = res.data.total;
    paperGroupDialogVisible.value = true;
    selectType.value = type;
    // 对表格移除选中
    nextTick(() => {
      if (isNew) {
        paperSelectTableRef.value.tableRef.clearSelection();
        // 不同type时赋值
        if (type === "1") {
          selectedPapers.value = form.value.singleChoiceQuestions || [];
        } else if (type === "2") {
          selectedPapers.value = form.value.multipleChoiceQuestions || [];
        } else if (type === "3") {
          selectedPapers.value = form.value.fillBlankQuestions || [];
        }
      }
      console.log(selectedPapers.value);
      if (type === "1") {
        // 找到选中的行
        const selectedRows = papersList.value.filter(
          item =>
            selectedPapers.value.findIndex(idx => idx.id === item.id) !== -1
        );
        if (selectedRows.length > 0) {
          selectedRows.forEach(row => {
            paperSelectTableRef.value.tableRef.toggleRowSelection(row, true);
          });
        }
      } else if (type === "2") {
        // 找到选中的行
        const selectedRows = papersList.value.filter(
          item =>
            selectedPapers.value.findIndex(idx => idx.id === item.id) !== -1
        );
        if (selectedRows.length > 0) {
          selectedRows.forEach(row => {
            console.log(row);
            paperSelectTableRef.value.tableRef.toggleRowSelection(row, true);
          });
        }
      } else {
        // 找到选中的行
        const selectedRows = papersList.value.filter(
          item =>
            selectedPapers.value.findIndex(idx => idx.id === item.id) !== -1
        );
        if (selectedRows.length > 0) {
          selectedRows.forEach(row => {
            console.log(row);
            paperSelectTableRef.value.tableRef.toggleRowSelection(row, true);
          });
        }
      }
    });
  });
};

// 分页
const handlePaperCurrentChange = (val: number) => {
  paperPagination.value.pageNum = val;
  addSingleChoiceQuestion(selectType.value);
};

// 分页大小改变
const handelPaperSizeChange = (val: number) => {
  paperPagination.value.pageSize = val;
  addSingleChoiceQuestion(selectType.value);
};

// 分页改变
const handleCurrentChange = (val: number) => {
  paperListParams.value.pageNum = val;
  queryPaperList();
};
const selectedPapers = ref([]);

// 确认选择试题
const handleSelectPapers = () => {
  selectedPapers.value = paperSelectTableRef.value.tableRef.getSelectionRows();
  // 判断selectType是单选题还是多选题还是填空题
  if (selectType.value === "1") {
    form.value.singleChoiceQuestions = selectedPapers.value;
    // 设置各类型题目的数量
    form.value.singleCount = selectedPapers.value.length;
  } else if (selectType.value === "2") {
    form.value.multipleChoiceQuestions = selectedPapers.value;
    form.value.multipleCount = selectedPapers.value.length;
  } else if (selectType.value === "3") {
    form.value.fillBlankQuestions = selectedPapers.value;
    form.value.blankCount = selectedPapers.value.length;
  }
  paperGroupDialogVisible.value = false;
};

// 取消选择试题
const handleCancelSelectPapers = () => {
  paperGroupDialogVisible.value = false;
};

// 分页大小改变
const handleSizeChange = (val: number) => {
  paperListParams.value.pageSize = val;
  queryPaperList();
};

// 选择试卷组
const handleSelectGroup = (val: string) => {
  paperListParams.value.groupName = val;
  queryPaperList();
};

// 搜索
const handleSearch = (val: string) => {
  paperListParams.value.name = val;
  queryPaperList();
};

// 试卷组下拉项
const paperGroupList = ref([]);
const queryPaperGroupList = async () => {
  try {
    const res = await getPaperGroupList();
    paperGroupList.value = res.data;
  } catch (error) {
    ElMessage.error("查询失败");
  }
};

onMounted(() => {
  queryPaperList();
  queryPaperGroupList();
});

// 确定生成试卷
const handleConfirm = async () => {
  if (dialogTitle.value === "新增试卷") {
    formRef.value.validate(async (valid: boolean) => {
      if (valid) {
        if (addPaperType.value === 1) {
          const res = await createPaper(form.value);
          if (res.code === 200) {
            ElMessage.success("生成试卷成功");
            dialogVisible.value = false;
            queryPaperList();
          } else {
            ElMessage.error(res.message);
          }
        } else {
          const params = {
            name: form.value.name,
            groupName: form.value.groupName,
            questionCount: form.value.questionCount,
            singleChoiceQuestions: form.value.singleChoiceQuestions?.map(
              (item: any) => item.id
            ),
            multipleChoiceQuestions: form.value.multipleChoiceQuestions?.map(
              (item: any) => item.id
            ),
            fillBlankQuestions: form.value.fillBlankQuestions?.map(
              (item: any) => item.id
            ),
            singleScore: Number(form.value.singleScore),
            multipleScore: Number(form.value.multipleScore),
            blankScore: Number(form.value.blankScore),
            totalScore: form.value.totalScore
          };
          const result = await generatePaper(params);
          if (result.code === 200) {
            ElMessage.success("生成试卷成功");
            dialogVisible.value = false;
            queryPaperList();
          } else {
            ElMessage.error(result.message);
          }
        }
      } else {
        ElMessage.error("请填写完整信息");
      }
    });
  } else {
    const res = await updatePaper(form.value);
    if (res.code === 200) {
      ElMessage.success("编辑试卷成功");
      dialogVisible.value = false;
      queryPaperList();
    } else {
      ElMessage.error(res.message);
    }
  }
};

// 修改试卷状态
const handleSwitchChange = async (row: any) => {
  const res = await updatePaperStatus(row.id, row.status);
  if (res.code === 200) {
    ElMessage.success("修改试卷状态成功");
    queryPaperList();
  } else {
    ElMessage.error(res.message);
    queryPaperList();
  }
};
</script>

<style scoped>
.paper-form {
  .number-input {
    width: 200px;
  }

  .el-select {
    width: 200px;
  }
}
</style>
